from django.shortcuts import render
from rest_framework.views import APIView
from QQLoginTool.QQtool import OAuthQQ
from rest_framework.response import Response
from django.conf import settings
from rest_framework import status

# Create your views here.
from oauth.models import OAuthQQUser
from oauth.serializers import QQAuthUserSerializer
from .utils import generate_token, generate_save_user_token
from carts.utils import merge_cart_cookie_to_redis

"""
当用户在前端登录界面点击 QQ登录按钮向后端发送请求 (获取QQ登录扫码url)
"""

class QQAuthURLView(APIView):
    def get(self, request):
        # request.query_params

        #提取前段通过查询参数传入的next（记录用来从那里跳转到登录）
        next = request.query_params.get('next')
        # print(type(request.query_params))
        if next is None:
            next = '/'

        #利用QQ登录SDK
        # oAuth = OAuthQQ(client_id=appid, client_secret=appkey, redirect_uri=回调url, state=从那里来到登录界面来源路径)
        oAuth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)

        #调用SDK中的方法获取拼接好的扫码登录url
        login_url = oAuth.get_qq_url()
        #响应扫码登录url
        return Response({'login_url': login_url})


class QQAuthUserView(APIView):
    """QQ扫码登录成功后的回调处理"""

    def get(self, request):
        #提取查询参数中的code
        code = request.query_params.get('code')
        # http: // www.meiduo.site: 8080 / oauth_callback.html?
        # code = CC9E2B7E985C68E656C79DC930B5F7A0 & state = % 2F

        #如果code没有提取到提前响应400

        if code is None:
            return Response({'message': 'code无效'}, status=status.HTTP_400_BAD_REQUEST)

        #创建QQ登录工具对象
        oAuth = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                        client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI)

        try:
            #向QQ服务器发送请求，用code获取access token
            access_token = oAuth.get_access_token(code)

            #再次向QQ服务器请求，用access token获取openid
            openid = oAuth.get_open_id(access_token)
        except Exception as errror:
            return Response({'message': 'QQ服务器异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 不绑定的情况下
        try:
             # 用openid去查询OAuthQQUser表中是否用这个openid
            oAuth_model = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 如果没有查到此openid，说明此openid没有绑定过美多商城用户，
            # 如果没有绑定过，创建一个新美多用户，和此openid绑定
            # 对openid进行加密，并返回
            openid_sign = generate_save_user_token(openid)

            # 响应时字典的key 由于前端写死了access_token 变量，所以我们要使用access_token
            return Response({'access_token': openid_sign})
        # 下面是用户已绑定了openid
        else:
            # 如果能查到openid。说明此openid已经绑定过美多商城的用户
            # 直接生成JWT token 响应回去，直接代表用户登录成功
            # OAuthQQUserd模型类点user外键获取user用户
            user = oAuth_model.user
            token = generate_token(user)

            response = Response({
                'user_id':user.id,
                'username': user.username,
                'token': token
            })
            #购物车合并
            merge_cart_cookie_to_redis(request, user, response)

            return response


    def post(self, request):
        """用openid 绑定美多商城用户"""
        # 1 .创建序列化器进行反序列化
        serializer = QQAuthUserSerializer(data=request.data)
        # 2. 调用序列化的校验方法
        serializer.is_valid(raise_exception=True)

        # 3. 调用序列化器的save 新增数据
        user = serializer.save()
        # 会调用序列化器中的create方法或update
        # 方法的返回值会作为序列化器save方法的返回值

        # 4. 生成JWT token
        token = generate_token(user)

        # 5. 响应
        response = Response({
            'user': user.id,
            'username': user.username,
            'token': token
        })
        # 购物车合并
        merge_cart_cookie_to_redis(request, user, response)

        return response